﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Media;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;



namespace Metropolicity
{
    class PlayScene : InteractableScene
    {
        //Background Positions
        private const int BACKGROUND_OFFSET_X = 400;
        private const int BACKGROUND_OFFSET_Y = 240;
        public ContentManager content;
        public PowerNode clicked;
        public Boolean stormInEffect;
        //Background GameObjects
        Texture2D developedNode1;
        Texture2D developedNode2;
        Texture2D developedNode3;
        Texture2D developedNode4;
        Texture2D developedNode5;
        Texture2D developedNode6;
        Texture2D developedNode7;
        Texture2D developedNode8;
        Texture2D developedNode9;
        Texture2D developedNode10;
        Texture2D developedNode11;
        Texture2D developedNode12;
        Texture2D developedNode13;
        Texture2D undevelopedNode1;
        Texture2D undevelopedNode2;
        Texture2D undevelopedNode3;
        Texture2D undevelopedNode4;
        Song song;
        private GameObject background;
        //Menu GameObjects
        private TokenGameObject buttonMenu;
        //Play Area GameObjects
        public List<Texture2D> developedNodeTextures;
        public List<PowerNode> powerNodes;
        public List<EnergyCell> energyCells;
        public List<UndevelopedNode> undevelopedNodes;
        public List<DevelopingNode> developingNodes;
        private PopupScoreScene popupScoreScene;
        private PopupMenuScene popupMenuScene;
        private PopupLoseScene popupLoseScene;
        //Game Data
        private Random rand;


        public PlayScene()
            : base()
        {
            this.sceneIndex = SceneIndex.PlayScene;
        }

        public override void Stop()
        {
            base.Stop();
            //Background GameObjects
            background = null;

            //Menu GameObjects
            buttonMenu = null;

            //Play Area GameObjects
            popupScoreScene = null;
            popupMenuScene = null;
            popupLoseScene = null;
        }

        public override void Start()
        {
            base.Start();
            lose = false;
            stormInEffect = false;

            developedNodeTextures = new List<Texture2D>();
            undevelopedNodes = new List<UndevelopedNode>();
            developingNodes = new List<DevelopingNode>();
            energyCells = new List<EnergyCell>();
            for (int y = 0; y <= Game1.CAMERA_HEIGHT / 32; y++)
            {
                for (int x = 0; x <= Game1.CAMERA_WIDTH / 64; x++)
                {
                    if ((y == 9 && x == 8) || (y == 8 && x == 6))
                        x++;
                    UndevelopedNode node = new UndevelopedNode(new Vector2(x * 64 - 32, y * 32 - 16));
                    gameObjects.Add(node);
                    undevelopedNodes.Add(node);
                }
            }
            for (int y = 0; y < Game1.CAMERA_HEIGHT / 32; y++)
            {
                for (int x = 0; x <= Game1.CAMERA_WIDTH / 64; x++)
                {
                    if ((y == 7 && x == 7) || (y == 9 && x == 6))
                        x++;
                    UndevelopedNode node = new UndevelopedNode(new Vector2(x * 64, y * 32));
                    gameObjects.Add(node);
                    undevelopedNodes.Add(node);
                }
            }

            powerNodes = new List<PowerNode>();
            PowerNode powerNode = new CoalPowerNode(this);
            gameObjects.Add(powerNode);
            powerNodes.Add(powerNode);

            powerNode = new SolarPowerNode(this);
            gameObjects.Add(powerNode);
            powerNodes.Add(powerNode);

            powerNode = new NuclearPowerNode(this);
            gameObjects.Add(powerNode);
            powerNodes.Add(powerNode);

            powerNode = new WindPowerNode(this);
            gameObjects.Add(powerNode);
            powerNodes.Add(powerNode);

            //Game Data Initialization
            rand = new Random();
            if (this.options != null)
            {
                // this.options.TryGetValue("language", out this.language);
            }
            popupScoreScene = new PopupScoreScene();
            popupMenuScene = new PopupMenuScene();
            popupLoseScene = new PopupLoseScene();
            //Background Initialization
            background = new GameObject("background/playScene22", new Vector2(BACKGROUND_OFFSET_X, BACKGROUND_OFFSET_Y));
            background.zindex = 0.1f;
            gameObjects.Add(background);

            //Menu Initialization

            //Play Area Initialization

        }

        public override void LoadContent(ContentManager content)
        {
            this.content = content;
            developedNode1 = content.Load<Texture2D>("developedNode1");
            developedNode2 = content.Load<Texture2D>("developedNode2");
            developedNode3 = content.Load<Texture2D>("developedNode3");
            developedNode4 = content.Load<Texture2D>("developedNode4");
            developedNode5 = content.Load<Texture2D>("developedNode5");
            developedNode6 = content.Load<Texture2D>("developedNode6");
            developedNode7 = content.Load<Texture2D>("developedNode7");
            developedNode8 = content.Load<Texture2D>("developedNode8");
            developedNode9 = content.Load<Texture2D>("developedNode9");
            developedNode10 = content.Load<Texture2D>("developedNode10");
            developedNode11 = content.Load<Texture2D>("developedNode11");
            developedNode12 = content.Load<Texture2D>("developedNode12");
            developedNode13 = content.Load<Texture2D>("developedNode13");
            song = content.Load<Song>("inGameMusic");
            developedNodeTextures.Add(developedNode1);
            developedNodeTextures.Add(developedNode2);
            developedNodeTextures.Add(developedNode3);
            developedNodeTextures.Add(developedNode4);
            developedNodeTextures.Add(developedNode5);
            developedNodeTextures.Add(developedNode6);
            developedNodeTextures.Add(developedNode7);
            developedNodeTextures.Add(developedNode8);
            developedNodeTextures.Add(developedNode9);
            developedNodeTextures.Add(developedNode10);
            developedNodeTextures.Add(developedNode11);
            developedNodeTextures.Add(developedNode12);
            developedNodeTextures.Add(developedNode13);

            undevelopedNode1 = content.Load<Texture2D>("undevelopedNode1");
            undevelopedNode2 = content.Load<Texture2D>("undevelopedNode2");
            undevelopedNode3 = content.Load<Texture2D>("undevelopedNode3");
            undevelopedNode4 = content.Load<Texture2D>("undevelopedNode4");
            this.popupScoreScene.LoadContent(content);
            this.popupMenuScene.LoadContent(content);
            this.popupLoseScene.LoadContent(content);
            base.LoadContent(content);
            MediaPlayer.Play(song);           
        }

        public override void Update(GameTime gameTime)
        {
            if (developingNodes.Count == 0)
            {

                while (undevelopedNodes.Count > 0 && developingNodes.Count < 5)
                {
                    int zoningNode = rand.Next(0, undevelopedNodes.Count);
                    DevelopingNode developingNode = new DevelopingNode(undevelopedNodes[zoningNode].texturePath, undevelopedNodes[zoningNode].position, rand.Next(1, 5));
                    developingNode.setTexture(undevelopedNode2);
                    //developingNode.LoadContent(content);
                    developingNodes.Add(developingNode);

                    gameObjects.Remove(undevelopedNodes[zoningNode]);
                    gameObjects.Add(developingNode);
                    undevelopedNodes[zoningNode] = null;
                    undevelopedNodes.RemoveAt(zoningNode);
                }
                
            }
            foreach (EnergyCell energyCell in energyCells)
            {
                foreach (DevelopingNode developingNode in developingNodes)
                {
                    if (energyCell.rectangle.Intersects(developingNode.rectangle))
                    {
                        int tempPower = developingNode.requiredPower;
                        developingNode.Transform(energyCell.power);
                        energyCell.givePower(tempPower);

                    }
                }
            }
            int x = 0;
            while (x < energyCells.Count)
            {
                if (energyCells[x].power <= 0)
                {
                    gameObjects.Remove(energyCells[x]);
                    energyCells.RemoveAt(x);
                }
                else
                    x++;
            }
            x = 0;
            while (x < developingNodes.Count)
            {
                switch (developingNodes[x].requiredPower)
                {
                    case 1:
                        developingNodes[x].texture = undevelopedNode1;
                        break;
                    case 2:
                        developingNodes[x].texture = undevelopedNode2;
                        break;
                    case 3:
                        developingNodes[x].texture = undevelopedNode3;
                        break;
                    case 4:
                        developingNodes[x].texture = undevelopedNode4;
                        break;
                    default:
                        DevelopedNode developedNode = new DevelopedNode(developingNodes[x].position);
                        developedNode.setTexture(developedNodeTextures[rand.Next(0, developedNodeTextures.Count)]);
                        gameObjects.Remove(developingNodes[x]);
                        developingNodes.RemoveAt(x);
                        gameObjects.Add(developedNode);
                        x--;
                        GameObject.previousScale = GameObject.scale;
                GameObject.scale -= .01f;

                foreach (GameObject gameObject in gameObjects)
                {
                    gameObject.ScaleUpdate();
                }
                        break;
                }
                x++;
            }
            foreach (PowerNode powerNode in powerNodes)
            {
                powerNode.timeKeepsOnTicking(gameTime);
            } 
           
#if WINDOWS_PHONE
            if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
            {
                this.control = SceneControls.Goto;
                this.sceneIndex = SceneIndex.MenuScene;
                this.end = true;
            }
#endif
            if (!this.popupScoreScene.dismissed)
            {
                this.popupScoreScene.Update(gameTime);
            }
            else if (!this.popupMenuScene.dismissed)
            {
                this.popupMenuScene.Update(gameTime);
                if (this.popupMenuScene.exit)
                {
                    this.control = SceneControls.Goto;
                    this.sceneIndex = SceneIndex.MenuScene;
                    this.end = true;
                }
                else if (this.popupMenuScene.newGame)
                {
                    this.control = SceneControls.Reset;
                    this.end = true;
                }
            }
            else if (!this.popupLoseScene.dismissed)
            {
                this.popupLoseScene.Update(gameTime);
                if (this.popupLoseScene.newGame)
                {
                    this.control = SceneControls.Reset;
                    this.end = true;
                }
            }
            else
            {

                //  if (clicked == buttonMenu)
                // {
                //     this.popupMenuScene.dismissed = false;
                // }

                base.Update(gameTime);
                if (clicked == null)
                {
                    if (highlighted != null)
                    {
                        foreach (PowerNode powerNode in powerNodes)
                        {
                            if (powerNode == highlighted && powerNode.energyCell != null)
                                clicked = powerNode;
                        }
                    }
                }
                else
                {
                    if (!new Rectangle(cursor.mouse.X, cursor.mouse.Y, 1, 1).Intersects(clicked.collisionRectangle))
                    {
                        clicked.energyCell.velocity = new Vector2(cursor.mouse.X - clicked.collisionRectangle.Center.X, cursor.mouse.Y - clicked.collisionRectangle.Center.Y);
                        gameObjects.Add(clicked.energyCell);
                        energyCells.Add(clicked.energyCell);
                        clicked.energyCell = null;
                        clicked = null;
                        highlighted = null;
                    }
                }
            }
        }

        public override void Draw(SpriteBatch spriteBatch)
        {
            if (!this.popupScoreScene.dismissed)
            {
                this.popupScoreScene.Draw(spriteBatch);
            }
            else if (!this.popupMenuScene.dismissed)
            {
                this.popupMenuScene.Draw(spriteBatch);
            }
            else if (!this.popupLoseScene.dismissed)
            {
                this.popupLoseScene.Draw(spriteBatch);
            }
            base.Draw(spriteBatch);
        }
    }
}